package org.yaac.client.activity;

import javax.inject.Inject;

import org.yaac.client.channel.ChannelClientManager;
import org.yaac.client.place.EGQLPlace;
import org.yaac.client.service.EGQLServiceAsync;
import org.yaac.client.ui.EGQLView;
import org.yaac.client.widget.BlockingAsyncCallback;
import org.yaac.shared.egql.Request;
import org.yaac.shared.egql.Response;

import com.google.gwt.event.shared.EventBus;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.AcceptsOneWidget;

/**
 * @author Max Zhu (thebbsky@gmail.com)
 *
 */
public class EGQLActivity extends SinglePlaceActivity<EGQLPlace> implements EGQLView.Presenter {

	private final EGQLView view;
	
	private final EGQLServiceAsync queryService;
	
	/**
	 * @param view
	 * @param queryService
	 * @param channelManager
	 */
	@Inject
	EGQLActivity(EGQLView view, EGQLServiceAsync queryService, 
			ChannelClientManager channelManager) {
		super();
		this.view = view;
		this.queryService = queryService;
		
		channelManager.subscribe(new ChannelClientManager.Listener() {
			@Override
			public void onMessage(String msg) {
				pushMessage(msg);
			}
		});
	}

	/**
	 * on server message pushed via channel service
	 * 
	 * normally this is an update on executed query
	 */
	private void pushMessage(String msg) {
		view.onMessage(msg);
	}
	
	@Override
	public void start(AcceptsOneWidget containerWidget, EventBus eventBus) {
		view.setPresenter(this);
		containerWidget.setWidget(view.asWidget());
	}

	@Override
	public SinglePlaceActivity<EGQLPlace> withPlace(EGQLPlace place) {
		return this;
	}

	@Override
	public void execute(String command, int batchSize, int maxResult) {
		queryService.execute(new Request(command, batchSize, maxResult), 
				new BlockingAsyncCallback<Response>() {

			@Override
			public void onBlockingCallSuccess(Response result) {
				onResponse(result);
			}

			@Override
			public void onBlockingCallFailure(Throwable caught) {
				// TODO client logging to server side
				// should not happen
				Window.alert("caught error:" + caught.getMessage() + " This is potentially a bug of Yaac, please contact us on this issue.");
			}
		});
	}
	
	private void onResponse(Response response) {
		switch(response.getStatus()) {
		case SYNTAX_ERROR:
			view.onSyntaxError(response.getMessage());
			break;
		case LOGICAL_ERROR:
			view.onLogicalError(response.getErrorCode());
			break;
		case SUCCESS:
			view.prepareResultPanels(response.getResponseMap());
			view.generateImmediateResultPanel(response.getImmediateStmts());
			break;
		}
	}
}
